<?php

namespace Fomo\Redis;

/**
 * class Redis
 *
 * Strings methods
 * @method static bool connect($host,$port = 6379,$timeout = 0.0,$reserved = null,$retryInterval = 0,$readTimeout = 0.0)
 * @method static bool open($host,$port = 6379,$timeout = 0.0,$reserved = null,$retryInterval = 0,$readTimeout = 0.0)
 * @method static bool isConnected()
 * @method static string|false getHost()
 * @method static int|false getPort()
 * @method static int|false getDbNum()
 * @method static float|false getTimeout()
 * @method static float|bool getReadTimeout()
 * @method static string|null|bool getPersistentID()
 * @method static string|null|bool getAuth()
 * @method static bool pconnect($host,$port = 6379,$timeout = 0.0,$persistentId = null,$retryInterval = 0,$readTimeout = 0.0)
 * @method static bool popen($host,$port = 6379,$timeout = 0.0,$persistentId = null,$retryInterval = 0,$readTimeout = 0.0)
 * @method static bool close()
 * @method static bool swapdb(int $db1, int $db2)
 * @method static bool setOption($option, $value)
 * @method static mixed|null getOption($option)
 * @method static bool|string ping($message = null)
 * @method static string|\Redis echo($message)
 * @method static string|mixed|false|\Redis get($key)
 * @method static bool|\Redis set($key, $value, $timeout = null)
 * @method static bool|\Redis setex($key, $expire, $value)
 * @method static bool|\Redis psetex($key, $expire, $value)
 * @method static bool|array|\Redis setnx($key, $value)
 * @method static int|\Redis del($key1, ...$otherKeys)
 * @method static int|\Redis delete($key1, $key2 = null, $key3 = null)
 * @method static int|\Redis unlink($key1, $key2 = null, $key3 = null)
 * @method static \Redis multi($mode = \Redis::MULTI)
 * @method static \Redis pipeline()
 * @method static void|array|\Redis exec()
 * @method static discard()
 * @method static void|\Redis watch($key)
 * @method static unwatch()
 * @method static mixed|null|\Redis subscribe($channels, $callback)
 * @method static mixed|\Redis psubscribe($patterns, $callback)
 * @method static int|\Redis publish($channel, $message)
 * @method static array|int|\Redis pubsub($keyword, $argument)
 * @method static unsubscribe($channels = null)
 * @method static punsubscribe($patterns = null)
 * @method static int|bool|\Redis exists($key)
 * @method static int|\Redis incr($key)
 * @method static float|\Redis incrByFloat($key, $increment)
 * @method static int|\Redis incrBy($key, $value)
 * @method static int|\Redis decr($key)
 * @method static int|\Redis decrBy($key, $value)
 * @method static int|false|\Redis lPush($key, ...$value1)
 * @method static int|false|\Redis rPush($key, ...$value1)
 * @method static int|false|\Redis lPushx($key, $value)
 * @method static int|false|\Redis rPushx($key, $value)
 * @method static mixed|bool|\Redis lPop($key)
 * @method static mixed|bool|\Redis rPop($key)
 * @method static array|\Redis blPop($keys, $timeout)
 * @method static array|\Redis brPop(array $keys, $timeout)
 * @method static int|bool|\Redis lLen($key)
 * @method static int|\Redis lSize($key)
 * @method static mixed|bool|\Redis lIndex($key, $index)
 * @method static mixed|bool|\Redis lGet($key, $index)
 * @method static bool|\Redis lSet($key, $index, $value)
 * @method static array|\Redis lRange($key, $start, $end)
 * @method static array|\Redis lGetRange($key, $start, $end)
 * @method static array|false|\Redis lTrim($key, $start, $stop)
 * @method static listTrim($key, $start, $stop)
 * @method static int|bool|\Redis lRem($key, $value, $count)
 * @method static lRemove($key, $value, $count)
 * @method static int|\Redis lInsert($key, $position, $pivot, $value)
 * @method static int|bool|\Redis sAdd($key, ...$value1)
 * @method static int|\Redis sRem($key, ...$member1)
 * @method static sRemove($key, ...$member1)
 * @method static bool|\Redis sMove($srcKey, $dstKey, $member)
 * @method static bool|\Redis sIsMember($key, $value)
 * @method static sContains($key, $value)
 * @method static int|\Redis sCard($key)
 * @method static string|mixed|array|bool|\Redis sPop($key, $count = 1)
 * @method static string|mixed|array|bool|\Redis sRandMember($key, $count = 1)
 * @method static array|false|\Redis sInter($key1, ...$otherKeys)
 * @method static int|false|\Redis sInterStore($dstKey, $key1, ...$otherKeys)
 * @method static array|\Redis sUnion($key1, ...$otherKeys)
 * @method static int|\Redis sUnionStore($dstKey, $key1, ...$otherKeys)
 * @method static array|\Redis sDiff($key1, ...$otherKeys)
 * @method static int|false|\Redis sDiffStore($dstKey, $key1, ...$otherKeys)
 * @method static array|\Redis sMembers($key)
 * @method static array|\Redis sGetMembers($key)
 * @method static array|false|\Redis sScan($key, &$iterator, $pattern = null, $count = 0)
 * @method static string|mixed|\Redis getSet($key, $value)
 * @method static string|\Redis randomKey()
 * @method static bool|\Redis select($dbIndex)
 * @method static bool|\Redis move($key, $dbIndex)
 * @method static bool|\Redis rename($srcKey, $dstKey)
 * @method static renameKey($srcKey, $dstKey)
 * @method static bool|\Redis renameNx($srcKey, $dstKey)
 * @method static bool|\Redis expire($key, $ttl)
 * @method static bool|\Redis pExpire($key, $ttl)
 * @method static bool|\Redis setTimeout($key, $ttl)
 * @method static bool|\Redis expireAt($key, $timestamp)
 * @method static bool|\Redis pExpireAt($key, $timestamp)
 * @method static array|\Redis keys($pattern)
 * @method static getKeys($pattern)
 * @method static int|\Redis dbSize()
 * @method static bool|\Redis auth($password)
 * @method static bool|\Redis bgrewriteaof()
 * @method static bool|\Redis slaveof($host = '127.0.0.1', $port = 6379)
 * @method static mixed|\Redis slowLog(string $operation, int $length = null)
 * @method static string|int|false|\Redis object($string = '', $key = '')
 * @method static bool|\Redis save()
 * @method static bool|\Redis bgsave()
 * @method static int|\Redis lastSave()
 * @method static int|\Redis wait($numSlaves, $timeout)
 * @method static int|\Redis type($key)
 * @method static int|\Redis append($key, $value)
 * @method static string|\Redis getRange($key, $start, $end)
 * @method static substr($key, $start, $end)
 * @method static int|\Redis setRange($key, $offset, $value)
 * @method static int|\Redis strlen($key)
 * @method static int|\Redis bitpos($key, $bit, $start = 0, $end = null)
 * @method static int|\Redis getBit($key, $offset)
 * @method static int|\Redis setBit($key, $offset, $value)
 * @method static int|\Redis bitCount($key)
 * @method static int|\Redis bitOp($operation, $retKey, $key1, ...$otherKeys)
 * @method static bool|\Redis flushDB()
 * @method static bool|\Redis flushAll()
 * @method static array|\Redis sort($key, $option = null)
 * @method static array|\Redis info($option = null)
 * @method static array|\Redis role()
 * @method static bool|\Redis resetStat()
 * @method static int|bool|\Redis ttl($key)
 * @method static int|bool|\Redis pttl($key)
 * @method static bool|\Redis persist($key)
 * @method static bool|\Redis mset(array $array)
 * @method static array|\Redis getMultiple(array $keys)
 * @method static array|\Redis mGet(array $array)
 * @method static int|\Redis msetnx(array $array)
 * @method static string|mixed|false|\Redis rPopLPush($srcKey, $dstKey)
 * @method static string|mixed|bool|\Redis bRPopLPush($srcKey, $dstKey, $timeout)
 * @method static int|\Redis zAdd($key, $options, $score1, $value1 = null, $score2 = null, $value2 = null, $scoreN = null, $valueN = null)
 * @method static array|\Redis zRange($key, $start, $end, $withscores = null)
 * @method static int|\Redis zRem($key, $member1, ...$otherMembers)
 * @method static int|\Redis zDelete($key, $member1, ...$otherMembers)
 * @method static array|\Redis zRevRange($key, $start, $end, $withscore = null)
 * @method static array|\Redis zRangeByScore($key, $start, $end, array $options = [])
 * @method static array|\Redis zRevRangeByScore($key, $start, $end, array $options = [])
 * @method static array|false|\Redis zRangeByLex($key, $min, $max, $offset = null, $limit = null)
 * @method static array|\Redis zRevRangeByLex($key, $min, $max, $offset = null, $limit = null)
 * @method static int|\Redis zCount($key, $start, $end)
 * @method static int|\Redis zRemRangeByScore($key, $start, $end)
 * @method static zDeleteRangeByScore($key, $start, $end)
 * @method static int|\Redis zRemRangeByRank($key, $start, $end)
 * @method static zDeleteRangeByRank($key, $start, $end)
 * @method static int|\Redis zCard($key)
 * @method static int|\Redis zSize($key)
 * @method static float|bool|\Redis zScore($key, $member)
 * @method static int|false|\Redis zRank($key, $member)
 * @method static int|false|\Redis zRevRank($key, $member)
 * @method static float|\Redis zIncrBy($key, $value, $member)
 * @method static int|\Redis zUnionStore($output, $zSetKeys, ?array $weights = null, $aggregateFunction = 'SUM')
 * @method static zUnion($Output, $ZSetKeys, array $Weights = null, $aggregateFunction = 'SUM')
 * @method static int|\Redis zInterStore($output, $zSetKeys, array $weights = null, $aggregateFunction = 'SUM')
 * @method static zInter($Output, $ZSetKeys, array $Weights = null, $aggregateFunction = 'SUM')
 * @method static array|false|\Redis zScan($key, &$iterator, $pattern = null, $count = 0)
 * @method static array|\Redis bzPopMax($key1, $key2, $timeout)
 * @method static array|\Redis bzPopMin($key1, $key2, $timeout)
 * @method static array|\Redis zPopMax($key, $count = 1)
 * @method static array|\Redis zPopMin($key, $count = 1)
 * @method static int|bool|\Redis hSet($key, $hashKey, $value)
 * @method static bool|\Redis hSetNx($key, $hashKey, $value)
 * @method static string|false|\Redis hGet($key, $hashKey)
 * @method static int|false|\Redis hLen($key)
 * @method static int|bool|\Redis hDel($key, $hashKey1, ...$otherHashKeys)
 * @method static array|\Redis hKeys($key)
 * @method static array|\Redis hVals($key)
 * @method static array|\Redis hGetAll($key)
 * @method static bool|\Redis hExists($key, $hashKey)
 * @method static int|\Redis hIncrBy($key, $hashKey, $value)
 * @method static float|\Redis hIncrByFloat($key, $field, $increment)
 * @method static bool|\Redis hMSet($key, $hashKeys)
 * @method static array|\Redis hMGet($key, $hashKeys)
 * @method static array|\Redis hScan($key, &$iterator, $pattern = null, $count = 0)
 * @method static int|\Redis hStrLen(string $key, string $field)
 * @method static int|\Redis geoAdd($key, $longitude, $latitude, $member)
 * @method static array|\Redis geoHash($key, ...$member)
 * @method static array|\Redis geoPos(string $key, string $member)
 * @method static float|\Redis geoDist($key, $member1, $member2, $unit = null)
 * @method static mixed|\Redis geoRadius($key, $longitude, $latitude, $radius, $unit, array $options = null)
 * @method static array|\Redis geoRadiusByMember($key, $member, $radius, $units, array $options = null)
 * @method static array|\Redis config($operation, $key, $value)
 * @method static mixed|\Redis eval($script, $args = [], $numKeys = 0)
 * @method static mixed|\Redis evaluate($script, $args = [], $numKeys = 0)
 * @method static mixed|\Redis evalSha($scriptSha, $args = [], $numKeys = 0)
 * @method static evaluateSha($scriptSha, $args = [], $numKeys = 0)
 * @method static mixed|\Redis script($command, $script)
 * @method static string|null getLastError()
 * @method static bool clearLastError()
 * @method static mixed client($command, $value = '')
 * @method static string _prefix($value)
 * @method static mixed _unserialize($value)
 * @method static mixed _serialize($value)
 * @method static string|false dump($key)
 * @method static bool restore($key, $ttl, $value)
 * @method static bool migrate($host, $port, $key, $db, $timeout, $copy = false, $replace = false)
 * @method static array time()
 * @method static array|false|\Redis scan(&$iterator, $pattern = null, $count = 0)
 * @method static bool|\Redis pfAdd($key, array $elements)
 * @method static int|\Redis pfCount($key)
 * @method static bool|\Redis pfMerge($destKey, array $sourceKeys)
 * @method static mixed|\Redis rawCommand($command, $arguments)
 * @method static int|\Redis getMode()
 * @method static int|\Redis xAck($stream, $group, $messages)
 * @method static string|\Redis xAdd($key, $id, $messages, $maxLen = 0, $isApproximate = false)
 * @method static array|\Redis xClaim($key, $group, $consumer, $minIdleTime, $ids, $options = [])
 * @method static int|\Redis xDel($key, $ids)
 * @method static mixed|\Redis xGroup($operation, $key, $group, $msgId = '', $mkStream = false)
 * @method static mixed|\Redis xInfo($operation, $stream, $group)
 * @method static int|\Redis xLen($stream)
 * @method static array|\Redis xPending($stream, $group, $start = null, $end = null, $count = null, $consumer = null)
 * @method static array|\Redis xRange($stream, $start, $end, $count = null)
 * @method static array|\Redis xRead($streams, $count = null, $block = null)
 * @method static array|\Redis xReadGroup($group, $consumer, $streams, $count = null, $block = null)
 * @method static array|\Redis xRevRange($stream, $end, $start, $count = null)
 * @method static int|\Redis xTrim($stream, $maxLen, $isApproximate)
 * @method static int|bool|\Redis sAddArray($key, array $values)
 */

class Redis
{
    protected static \Redis $instance;

    public static function setInstance(): void
    {
        self::$instance = new \Redis();

        self::$instance->connect(config('redis.host') , config('redis.port'));
        self::$instance->select(config('redis.database'));

        if (! is_null(config('redis.username')) && ! is_null(config('redis.password'))){
            self::$instance->auth([config('redis.username') , config('redis.password')]);
        }
    }

    public static function getInstance(): \Redis
    {
        return self::$instance;
    }

    public static function __callStatic(string $method, array $arguments)
    {
        return self::$instance->$method(...$arguments);
    }
}